package com.fowo.api.syncAmazon.core.sync;

import com.amazon.spapi.model.reports.CreateReportSpecification;
import com.amazon.spapi.model.reports.Report;
import com.amazon.spapi.model.reports.ReportDocument;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.syncAmazon.core.AbstractAmazonSyncData;
import com.fowo.api.syncAmazon.core.ReportApiType;
import com.fowo.api.syncAmazon.entity.ApiDefine;
import com.fowo.api.syncAmazon.entity.ApiRequestLog;
import com.fowo.api.syncAmazon.entity.TmpFbaShipmentReport;
import com.fowo.api.syncAmazon.service.TmpFbaShipmentReportService;
import com.fowo.api.syncAmazon.service.impl.TmpFbaShipmentReportServiceImpl;
import com.fowo.api.syncAmazon.util.AmzDateUtils;
import com.fowo.api.syncAmazon.util.GeneralUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;

/**
 * @fileName: FBAShipmentsDataSync
 * @Description: FBA配送货件报告同步
 * @Author: yyf
 * @Date: 2024/3/1 0001 9:30
 */
@Component
public class FBAShipmentsReportSync extends AbstractAmazonSyncData {
    @Resource
    private TmpFbaShipmentReportServiceImpl tmpFbaShipmentReportService;
    private ApiDefine apiDefine = ApiDefine.builder()
            .apiCode("fba_shipments_report")
            .initdate(1)
            .timeInterval(1)
            .timeIntervalType("day").build();

    @Override
    protected ApiDefine setApiDefine() {
        return apiDefine;
    }

    @Override
    protected void requestData() throws Exception {
        // 获取卖家账号信息
        String platform = "Amazon";
        this.getAuthority(platform);
        // 查询该账号下所有店铺
        LambdaQueryWrapper<ShopInfo> shopInfosWrapper = new LambdaQueryWrapper<>();
        shopInfosWrapper.eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01");
        List<ShopInfo> shopInfoList = shopInfoServiceImpl.list(shopInfosWrapper);

        // 清空临时表
        tmpFbaShipmentReportService.cleanAll();

        //请求报告
        // fba配送货件报告，与店铺没有关系，这与卖家账号有关
        ShopInfo shopInfo = shopInfoList.get(0);
        //创建报告 -查询参数
        List<String> marketplaceIds = Arrays.asList(shopInfo.getMarketplaceId().split(","));
        CreateReportSpecification body = new CreateReportSpecification();
        body.setReportType(ReportApiType.GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL);
        body.setMarketplaceIds(marketplaceIds);
        // 获取拉取的时间区间
        body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(startTime));
        body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(endTime));

        // 第一步 创建报告
        final String reportId = retryCreateReport(shopInfo, body);
        // 第二步 检验报告是否完成
        Report report = retryCheckReport(shopInfo, reportId);
        // 第三步 获取报告连接
        ReportDocument reportDocument = getReportDocument(shopInfo,report.getReportDocumentId());
        System.out.println(reportDocument.getUrl());

        if (reportDocument != null) {
            String compressionAlgorithm = reportDocument.getCompressionAlgorithm() != null ? reportDocument.getCompressionAlgorithm().getValue() : null;
            BufferedReader reader = this.getAndUnzipReport(reportDocument.getUrl(), compressionAlgorithm);
            try {
                download(reader, shopInfo);
            }catch (Exception ex){
                apiRequestLog.setErrorMessage("缓存至临时表异常："+ex);
                apiRequestLog.setStatus(ApiRequestLog.FAIL);
                apiRequestLogService.getBaseMapper().updateById(apiRequestLog);
                throw new RuntimeException(ex);
            }finally {
                reader.close();
            }
        }
    }

    @Override
    protected <T> void download(T param, ShopInfo shop) throws IOException, IllegalArgumentException {
        BufferedReader reader = null;
        if (param instanceof BufferedReader){
            try {
                reader = (BufferedReader)param;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }

        int lineNumber = 0;
        String line = null;
        Map<String,Integer> titleList = new HashMap<>();
        List<TmpFbaShipmentReport> list = new ArrayList<>();

        while ((line = reader.readLine()) != null) {
            String[] info = line.split("\t");
            int length = info.length;
            if (lineNumber == 0) {
                for (int i = 0; i < length; i++) {
                    titleList.put(info[i],i);
                }
            } else {
                TmpFbaShipmentReport tmp = new TmpFbaShipmentReport();
                Map<String, Object> fields = this.getFieldsFromInfo(info, titleList);

                tmp.setAmazonOrderId(fields.get("amazon-order-id").toString());
                tmp.setMerchantOrderId(fields.get("merchant-order-id").toString());
                tmp.setShipmentId(fields.get("shipment-id").toString());
                tmp.setShipmentItemId(fields.get("shipment-item-id").toString());
                tmp.setAmazonOrderItemId(fields.get("amazon-order-item-id").toString());
                tmp.setMerchantOrderItemId(fields.get("merchant-order-item-id").toString());
                tmp.setPurchaseDate(GeneralUtil.getDate(fields.get("purchase-date")));
                tmp.setPaymentDate(GeneralUtil.getDate(fields.get("payments-date")));
                tmp.setShipmentDate(GeneralUtil.getDate(fields.get("shipment-date")));
                tmp.setReportingDate(GeneralUtil.getDate(fields.get("reporting-date")));
                tmp.setBuyerEmail(fields.get("buyer-email").toString());
                tmp.setBuyerName(fields.get("buyer-name").toString());
                tmp.setBuyerPhoneNumber(fields.get("buyer-phone-number").toString());
                tmp.setSku(fields.get("sku").toString());
                tmp.setProductName(fields.get("product-name").toString());
                tmp.setQuantityShipped(GeneralUtil.getIntegerValue(fields.get("quantity-shipped")));
                tmp.setCurrency(fields.get("currency").toString());
                tmp.setItemPrice(GeneralUtil.getBigDecimalValue(fields.get("item-price").toString()));
                tmp.setItemTax(GeneralUtil.getBigDecimalValue(fields.get("item-tax").toString()));
                tmp.setShippingPrice(GeneralUtil.getBigDecimal(fields.get("shipping-price").toString()));
                tmp.setShippingTax(GeneralUtil.getBigDecimal(fields.get("shipping-tax").toString()));
                tmp.setGiftWrapPrice(GeneralUtil.getBigDecimal(fields.get("gift-wrap-price").toString()));
                tmp.setGiftWrapTax(GeneralUtil.getBigDecimal(fields.get("gift-wrap-tax").toString()));
                tmp.setShipServiceLevel(fields.get("ship-service-level").toString());
                tmp.setRecipientName(fields.get("recipient-name").toString());
                tmp.setShipAddress1(fields.get("ship-address-1").toString());
                tmp.setShipAddress2(fields.get("ship-address-2").toString());
                tmp.setShipAddress3(fields.get("ship-address-3").toString());
                tmp.setShipCity(fields.get("ship-city").toString());
                tmp.setShipState(fields.get("ship-state").toString());
                tmp.setShipPostalCode(fields.get("ship-postal-code").toString());
                tmp.setShipCountry(fields.get("ship-country").toString());
                tmp.setShipPhoneNumber(fields.get("ship-phone-number").toString());
                tmp.setBillAddress1(fields.get("bill-address-1").toString());
                tmp.setBillAddress2(fields.get("bill-address-2").toString());
                tmp.setBillAddress3(fields.get("bill-address-3").toString());
                tmp.setBillCity(fields.get("bill-city").toString());
                tmp.setBillState(fields.get("bill-state").toString());
                tmp.setBillPostalCode(fields.get("bill-postal-code").toString());
                tmp.setBillCountry(fields.get("bill-country").toString());
                tmp.setItemPromotionDiscount(GeneralUtil.getBigDecimalValue(fields.get("item-promotion-discount").toString()));
                tmp.setShipPromotionDiscount(GeneralUtil.getBigDecimalValue(fields.get("ship-promotion-discount").toString()));
                tmp.setCarrier(fields.get("carrier").toString());
                tmp.setTrackingNumber(fields.get("tracking-number").toString());
                tmp.setEstimatedArrivalDate(GeneralUtil.getDate(fields.get("estimated-arrival-date")));
                tmp.setFulfillmentCenterId(fields.get("fulfillment-center-id").toString());
                tmp.setFulfillmentChannel(fields.get("fulfillment-channel").toString());
                tmp.setSalesChannel(fields.get("sales-channel").toString());

                list.add(tmp);

            }
            lineNumber++;
        }

        // 写入同步数据量
        Integer dataVolume = apiRequestLog.getDataVolume() == null ? 0 : apiRequestLog.getDataVolume();
        apiRequestLog.setDataVolume(dataVolume+list.size());

        tmpFbaShipmentReportService.saveBatch(list);
    }

    @Override
    protected void updateOrInsertData() {
        tmpFbaShipmentReportService.getBaseMapper().insertOrUpdate();

        // 完成本次同步日志
        apiDefine.setStatus(ApiDefine.SUCCESS);
        if(apiDefine.getLastDataTime() == null){
            apiDefine.setLastDataTime(endTime);
        } else if (endTime.after(apiDefine.getLastDataTime())) {
            apiDefine.setLastDataTime(endTime);
        }
        apiDefineService.getBaseMapper().updateById(apiDefine);
    }
}
